home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDXPRSV.500 / SECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  22.9 KB  |  955 lines

  1. /* sect.c */
  2.  
  3. /* 
  4.  * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
  5.  * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM 
  6.  *                  is busy. 
  7.  */
  8.  
  9. #include "obdefs.h"
  10. #include "osbind.h"
  11. #include "mydefs.h"
  12. #include "part.h"
  13. #include "hdx.h"
  14. #include "addr.h"
  15. #include "error.h"
  16.  
  17. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  18. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  19. #define MAXUNITS 16            /* max number of logical units */
  20.  
  21. #define PUNINFO struct _punifno
  22. PUNINFO {
  23.         WORD puns;    /* number of physical units */
  24.         BYTE pun[MAXUNITS];
  25.         LONG partition_start[MAXUNITS]; /* offset to partition on */
  26.                                         /* physical unit */
  27. };
  28. extern long ostack;        /* old stack pointer */
  29. extern UWORD errcode();        /* function to return error code */
  30. extern int yesscan;        /* the flag for the func. IBMGPART use */
  31. extern long sptrk;        /* the sector per track */
  32. extern int npart;        /* the number of partitions */
  33. extern int ext;            /* the index of extended partition */
  34. extern int showmany;    /* the flag for show the too many device alert box */
  35. extern char ttscsi;        /* the flag for SCSI if set */
  36. extern int t_scsi();    /* the assembly codes for check SCSI drive */
  37. extern int needscan;    /* TRUE: if it is the first time to scan the units */
  38. extern int noacsi;        /* set when the system there is not ST exist */
  39. extern int athead;        /* the # of data heads on the AT drive */
  40. extern int atcyl;        /* the # of cylinders on the AT drive */
  41. extern int atspt;        /* the # of sectors on the AT drive */
  42.  
  43. /*
  44.  * Logical-to-dev+partition mapping table.
  45.  */
  46. int nlogdevs;                /* # logical devices */
  47. LOGMAP logmap[EXTRALOGD];    /* logical dev map */
  48. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  49. int typedev = 0x0000;        /* if set, driver is a removable driver */
  50. int typedrv = 0x0000;        /* if set, driver is a SCSI driver */
  51. int atexst;                    /* set if AT drive exist */
  52. int slvexst;                /* set if AT slave drive exist */
  53. char useblit;                /* set for it is not a stbook drive */
  54.  
  55.  
  56. /*
  57.  * Rebuild logical-to-physical mapping
  58.  * by reading and interpreting the root
  59.  * blocks for all physical devs.
  60.  *
  61.  */
  62.  
  63. rescan(flag, znm)
  64.  
  65. int flag;    /* 0: don't report medium change error; */
  66.             /* non-0: report medium change error; */
  67. int znm;    /* 1: do zero & markbad; 0: do partition & format */
  68.  
  69. {
  70.     int dev, scan=0;
  71.     char buf[512];
  72.     char sendata[16];
  73.     int partno, ret, inqret, i;
  74.     PART *partinfo;
  75.     char mask = 0x80;    /* 7th bit is set on */
  76.     int setmask;
  77.     int maxloop;
  78.  
  79.     noacsi = 1;             /* assume there is a ST in the system */
  80.     ostack = Super(NULL);    /* set supervice mode */
  81.     ttscsi = chkscsi();        /* set the ttscsi flag if SCSI exists */
  82.     delay();
  83.     if ((atexst = chkide()))    { /* AT drive exist */
  84.         if (stbook())    {
  85.             useblit = 0;
  86.         } else {
  87.             useblit = chkblit();
  88.         }
  89.         if ((ret = identify(16, buf)) == OK)    {
  90.             gparmfc(&atcyl, &athead, &atspt);
  91.         } else {
  92.             delay();
  93.             Super(ostack);
  94.             ret = errcode(16);
  95.             if (tsterr(ret) != OK)
  96.                 return ERROR;
  97.             return(-3);
  98.         }
  99.     }
  100.     delay();
  101.     /*
  102.     if ((atexst) && (slvexst = slave()))    {  AT slave drive exist 
  103.         if ((ret = identify(17, buf)) == OK)    {
  104.             atscyl = getword(buf + 2);
  105.             atshead = getword(buf + 6);
  106.             atsspt = getword(buf + 12);
  107.             delay();
  108.         } else {
  109.             delay();
  110.             Super(ostack);
  111.             ret = errcode(17);
  112.             if (tsterr(ret) != OK)
  113.                 return ERROR;
  114.             return(-3);
  115.         }
  116.     }
  117.     */
  118.     delay();
  119.     Super(ostack);
  120.     /* set the scent message box */
  121.     if ((needscan) && (ttscsi))
  122.         dsplymsg(scanmsg);
  123.  
  124.     /* disable all logical and physical devs */
  125.     for (dev = 0; dev < EXTRALOGD; ++dev)
  126.         logmap[dev].lm_physdev = -1;
  127.  
  128.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  129.         livedevs[dev] = 0;
  130.  
  131.     /*
  132.      * Scan all physical devs
  133.      * and pick up partition structures.
  134.      */
  135.     nlogdevs = 0;
  136.     showmany = 0;
  137.     if (atexst)    {
  138.         maxloop = 18;
  139.         dev = 16;
  140.     } else if (ttscsi)    {
  141.         maxloop = 16;
  142.         dev = 8;
  143.     } else {
  144.         maxloop = 8;
  145.         dev = 0;
  146.     }
  147. rerescan:
  148.     for (; dev < maxloop; ++dev)
  149.     {
  150.         if (((dev == 16) && (atexst)) || ((dev == 17) && slvexst))    {
  151.             if ((ret = getroot(dev, buf, (SECTOR)0)) != 0)    {
  152.                 if (tsterr(ret) != OK)
  153.                     err(rootread);
  154.                 return(ERROR);
  155.             }
  156.             goto atst;        /* skip and do the AT stuff only */
  157.         }
  158.  
  159.         /* initialize the buffer */
  160.         for (i = 0; i < 16; i++)        {
  161.             sendata[i] = 0;
  162.         }
  163.  
  164.         /* check see the drive is a what kind of drive */
  165.            ostack = Super(NULL);
  166.            delay();
  167.         inqret = inquiry(dev, (WORD)16, sendata);
  168.            delay();
  169.            Super(ostack);
  170.         setmask = 0x0001;
  171.         if (inqret & 0x08)    { /* the device is busy */
  172.             continue;
  173.         }
  174.         /* ret not equal OK, it may be a regular hard drive */
  175.         if (inqret == OK)         {     /* it is not a regular hard drive */
  176.             if (sendata[0])      {    /* it is not a hard drive */
  177.                 continue;
  178.             } else if (sendata[1] & mask)    { /* it is a removable drive */
  179.                 ;            /* don't set the SCSI bit */
  180.             } else {
  181.                   /* it is a SCSI drive */
  182.                 /* set the relative bit, 1 is a SCSI, other is not */
  183.                 typedrv |= setmask << dev;
  184.             }
  185.         }
  186.         if ((ret = getroot(dev, buf, (SECTOR)0)) < 0) {
  187.             if (znm)  rangelog(dev);
  188.             continue;
  189.         } else {        /* ret >= 0 */
  190.             if (ret > 0) {
  191.                 if ((flag) && (tsterr(ret) == OK))        {    
  192.                 /* if non-0, report error if medium changed */
  193.                         erasemsg();
  194.                         return ERROR;
  195.                 }
  196.                 if ((ret = getroot(dev, buf, (SECTOR)0))) {    /* try again */
  197.                     if (ret > 0 && flag && tsterr(ret) == OK)    {
  198.                         erasemsg();
  199.                         return ERROR;
  200.                     } else if ((ret > 0) && (!flag))    {
  201.                         if ((inqret == OK) && (sendata[1] & mask))    { 
  202.                             /* it is a removable drive */
  203.                             /* but forget insert the cartridge */
  204.                             err(instdrv);
  205.                             erasemsg();
  206.                         }
  207.                     }
  208.                     if (znm)    {
  209.                         rangelog(dev);
  210.                     }
  211.                     continue;
  212.                 }
  213.             }
  214.             if (inqret == OK)     {  /* it is a SCSI drive */
  215.                 if (sendata[1] & mask)    { /* it is a removable drive */
  216.                     /* set the relative bit, 1 is a removable, other is not */
  217.                     typedev |= setmask << dev;
  218.                 }
  219.             }
  220.  
  221.         atst:
  222.             livedevs[dev] = 1;
  223.             if (dev < 7)    /* ST exist in the system */
  224.                 noacsi = 0;
  225.             yesscan = 1;
  226.             if (stgpart(dev, buf, (PART *)&partinfo) == ERROR)    {
  227.                 erasemsg();
  228.                 return ERROR;
  229.             }
  230.             if (ext != NO_EXT)    {
  231.                 sortpart(partinfo,SCAN_BS); 
  232.             }
  233.         for (partno = 0; partno < npart; ++partno) {
  234.             if ((partinfo[partno].p_flg & P_EXISTS) &&
  235.                 (partinfo[partno].p_siz != (SECTOR)0) &&
  236.                 (((partinfo[partno].p_id[0] == 'G') &&
  237.                  (partinfo[partno].p_id[1] == 'E') &&
  238.                  (partinfo[partno].p_id[2] == 'M'))   ||
  239.                  ((partinfo[partno].p_id[0] == 'B') &&
  240.                  (partinfo[partno].p_id[1] == 'G') &&
  241.                  (partinfo[partno].p_id[2] == 'M'))))   
  242.             {
  243.                 if (nlogdevs > EXTRALOGD)    {
  244.                     continue;
  245.                 }
  246.                 logmap[nlogdevs].lm_physdev = dev;
  247.                 logmap[nlogdevs].lm_partno = partno;
  248.                 logmap[nlogdevs].lm_start =  partinfo[partno].p_st;
  249.                 logmap[nlogdevs].lm_siz =      partinfo[partno].p_siz;
  250.                 ++nlogdevs;
  251.                 if (nlogdevs == MAXLOGDEVS)         {
  252.                     showmany = 1;
  253.                 }
  254.             }
  255.         }
  256.     }
  257.     inipart(partinfo, npart);
  258.     if (partinfo > 0)    Mfree(partinfo);
  259.     }
  260.     if ((maxloop > 16) && (ttscsi))        {
  261.         maxloop = 16;
  262.         dev = 8;
  263.         goto rerescan;
  264.     } else if (((maxloop > 16) && (!ttscsi)) || ((ttscsi)&&(maxloop>8)))    {
  265.         maxloop = 8;
  266.         dev = 0;
  267.         goto rerescan;
  268.     }
  269.     erasemsg();
  270.     return OK;
  271. }
  272.  
  273. /* rerange the partition informations into the order form. */
  274.  
  275.  sortpart(pinfo, type)
  276.  PART *pinfo;
  277.  int type;                /* USER_ED = 1: for user interface use */
  278.                          /* SCAN_BS = 0: for rescan() and laybs() use */
  279.  {
  280.      int i, j, k;
  281.     PART rpart[2];
  282.  
  283.     if (ext == NO_EXT) return OK;    /* don't need sort */
  284.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  285.         rpart[i].p_flg = 0L;
  286.         rpart[i].p_st = 0L;
  287.         rpart[i].p_siz = 0L;
  288.         for (k = 0; k < 3; k++)
  289.             rpart[i].p_id[k] = '0';
  290.     }
  291.     /* save the partitions that after the extened partitions */
  292.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  293.         if (pinfo[i].p_flg & P_EXISTS)    {
  294.             rpart[j].p_flg = P_EXISTS;
  295.             rpart[j].p_st = pinfo[i].p_st;
  296.             rpart[j].p_siz = pinfo[i].p_siz;
  297.             for (k = 0; k < 3; k++)
  298.                 rpart[j].p_id[k] = pinfo[i].p_id[k];
  299.         } 
  300.     }
  301.     /* move the extened partition to the front */
  302.      for (i=4, j = ext; i < npart; i++, j++)    {
  303.         if (pinfo[i].p_flg & P_EXISTS)    {
  304.             pinfo[j].p_flg = P_EXISTS;
  305.             pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
  306.             pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
  307.             for (k = 0; k < 3; k++)
  308.                 pinfo[j].p_id[k] = pinfo[i].p_id[k];
  309.         } else { j--;}    /* stay with that space */
  310.     }
  311.     /* copy the not extended partitions back after the extended partitions */
  312.      for (i=0; i < 2; i++, j++)    {
  313.         if (rpart[i].p_flg & P_EXISTS)    {
  314.             pinfo[j].p_flg = P_EXISTS;
  315.             pinfo[j].p_st = rpart[i].p_st;
  316.             pinfo[j].p_siz = rpart[i].p_siz;
  317.             for (k = 0; k < 3; k++)
  318.                 pinfo[j].p_id[k] = rpart[i].p_id[k];
  319.         } else {j--;}
  320.     }
  321.     for (i = j; i < npart; i++)    { /* set the rest to 0 */
  322.         pinfo[i].p_flg = 0L;
  323.         pinfo[i].p_st = 0L;
  324.         pinfo[i].p_siz = 0L;
  325.         for (k = 0; k < 3; k++)
  326.             pinfo[i].p_id[k] = '0';
  327.     }
  328. }
  329.  
  330.  
  331. /* rearrange the kept extented partition back to the normal scheme */ 
  332.  
  333.  mvkpbk(kpinfo, xpinfo)
  334.  
  335.  SAVEPART *kpinfo;
  336.  PART *xpinfo;
  337.  
  338.  {
  339.      int i, j, k;
  340.     SAVEPART rpart[2];
  341.  
  342.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  343.         rpart[i].savest = 0L;
  344.         rpart[i].savend = 0L;
  345.         rpart[i].saveflg = 0;
  346.     }
  347.     /* save the partitions that after the extened partitions */
  348.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  349.         if (kpinfo[i].saveflg & P_EXISTS)    {
  350.             rpart[j].saveflg = P_EXISTS;
  351.             rpart[j].savest = kpinfo[i].savest;
  352.             rpart[j].savend = kpinfo[i].savend;
  353.         } 
  354.     }
  355.     /* move the extened partition to the front */
  356.      for (i=4, j = ext; i < npart; i++, j++)    {
  357.         if (xpinfo[i].p_flg & P_EXISTS)    { /* use the PART info for this */
  358.             kpinfo[j].saveflg = kpinfo[i].saveflg;
  359.             kpinfo[j].savest = kpinfo[i].savest;
  360.             kpinfo[j].savend = kpinfo[i].savend;
  361.         } else {j--;}
  362.     }
  363.     /* copy the not extended partitions back after the extended partitions */
  364.      for (i=0; i < 2; i++, j++)    {
  365.         if (rpart[i].saveflg & P_EXISTS)    { 
  366.             kpinfo[j].saveflg = rpart[i].saveflg;
  367.             kpinfo[j].savest = rpart[i].savest;
  368.             kpinfo[j].savend = rpart[i].savend;
  369.         } 
  370.     }
  371.     for (i = j; i < MAXPART+3; i++)    { /* set the rest to 0 */
  372.         kpinfo[i].saveflg = 0;
  373.         kpinfo[i].savest = 0L;
  374.         kpinfo[i].savend = 0L;
  375.     }
  376. }
  377.  
  378.  
  379.  
  380. /* 
  381.  * check to find out the exist of device
  382.  */
  383.  
  384. rangelog(dev)
  385.  
  386. int dev;
  387.  
  388. {
  389.     PUNINFO *divinfo;
  390.     int devnum;
  391.  
  392.     ostack = Super(NULL);
  393.     divinfo = ((PUNINFO *) *((long *)(0x516)));
  394.     for (devnum = 0; devnum < MAXUNITS; ++devnum)    {
  395.         if ((int)(divinfo->pun[devnum] & 0x07) == dev)    {
  396.             delay();
  397.             nlogdevs++;
  398.         }
  399.     }
  400.     Super(ostack);
  401. }
  402.  
  403. /*
  404.  * From a PHYSICAL device unit (0->7)
  405.  * and a partition number (0->3), figure
  406.  * out the LOGICAL disk number ('C'->'P').
  407.  *
  408.  * return the LOGICAL disk number or
  409.  * ERROR if the PHYSICAL device doesn't exist.
  410.  *
  411.  */
  412. phys2log(pdev, pno)
  413. int  pdev;    /* physical device unit */
  414. int  pno;    /* partition number (0 -> 3) */
  415. {
  416.     int logdev;        /* index to step through partitions of a phys unit */
  417.  
  418.     for (logdev = 0; logdev < EXTRALOGD; logdev++) {
  419.         if (logmap[logdev].lm_physdev == pdev &&
  420.             logmap[logdev].lm_partno == pno)
  421.             return ('C'+logdev);
  422.     }
  423.     return ERROR;
  424. }
  425.  
  426.  
  427. /*
  428.  * Map block on logical device to
  429.  * block on physical device;
  430.  * return ERROR if the logical device
  431.  * doesn't exist.
  432.  */
  433. log2phys(adev, ablk)
  434. int *adev;
  435. SECTOR *ablk;
  436. {
  437.     int dev;
  438.     char xbuf[256];
  439.     
  440.     dev = *adev;
  441.     if (dev >= 0 && dev <= 17)
  442.     return OK;
  443.  
  444.     dev = toupper(dev);
  445.     if (dev >= 'C' && dev <= 
  446.                 ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
  447.     {
  448.     dev -= 'C';
  449.     *adev = logmap[dev].lm_physdev;
  450.     *ablk = logmap[dev].lm_start + *ablk;
  451.     return OK;
  452.     }
  453.  
  454.     return ERROR;
  455. }
  456.  
  457.  
  458.  
  459. /*
  460.  * Return physical starting block# of a partition
  461.  *
  462.  */
  463. SECTOR 
  464. logstart(ldev)
  465. int ldev;    /* logical device */
  466. {
  467.     ldev = toupper(ldev);
  468.     if (ldev >= 'C' && ldev <= 
  469.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  470.         ldev -= 'C';
  471.         return (logmap[ldev].lm_start);
  472.     }
  473.     return ERROR;
  474. }
  475.  
  476.  
  477.  
  478. /*
  479.  * Return physical starting block# of a partition's data block.
  480.  *
  481.  */
  482. SECTOR 
  483. logend(ldev)
  484. int ldev;    /* logical device */
  485. {
  486.     ldev = toupper(ldev);
  487.     if (ldev >= 'C' && ldev <= 
  488.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  489.         ldev -= 'C';
  490.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  491.     }
  492.     return ERROR;
  493. }
  494.  
  495.  
  496. #define    MFM 17        /* sectors per track for MFM */
  497. #define    RLL 26        /* sectors per track for RLL */
  498.  
  499.  
  500. /*
  501.  * Check if dev's root block is intact.
  502.  * Return number of sectors per track on disk.
  503.  *
  504.  */
  505.  
  506. chkroot(dev, bs)
  507. int dev;
  508. char *bs;
  509. {
  510.     extern long get3bytes();
  511.     extern long get4bytes();
  512.     SETMODE *mb;
  513.     int i, ret, set, scsidrv, mask=0x0001;
  514.     int page=4, bsiz;
  515.     int head, spt;
  516.     SECTOR size, msiz, cyl;    /* size of media */
  517.     char buf[512], sendata[32];
  518.     long dmaptr, tmpptr;
  519.     char *dmahigh=0xffff8609,
  520.          *dmamid=0xffff860b,
  521.          *dmalow=0xffff860d;
  522.     
  523.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  524.     
  525.     ret = OK;
  526.     if (dev == 16)    {        /* it is a IDE-AT drive */
  527.         msiz = (SECTOR)athead * (SECTOR)atcyl * (SECTOR)atspt;
  528.         if (size != msiz)
  529.             ret = ERROR;
  530.         return(ret);
  531.     } else if (dev > 7)    {    /* it is a scsi drive */
  532.         ostack = Super(NULL);
  533.         delay();
  534.         if ((ret = readcap(dev, 0, (long)0, sendata)) == OK) {
  535.             if (msiz = get4bytes(sendata))    {
  536.                 msiz += 1;
  537.                 delay();
  538.                 Super(ostack);
  539.                 goto chkend;
  540.             } 
  541.         } 
  542.         for (i = 0; i < 32; i++)
  543.             sendata[i] = 0;
  544.         if ((ret = mdsense(dev, 4, 0, 32, sendata)) == OK)    {
  545.             if((msiz=get3bytes(sendata+5)))    {
  546.                         delay();
  547.                         Super(ostack);
  548.                         goto chkend;
  549.             }
  550.         }
  551.         for (i = 0; i < 32; i++)
  552.             sendata[i] = 0;
  553.         if ((ret = mdsense(dev, 0, 0, 16, sendata)) == OK)    {
  554.             if((msiz=get3bytes(sendata+5)))    {
  555.                         delay();
  556.                         Super(ostack);
  557.                         goto chkend;
  558.             }
  559.         }
  560.         for (i = 0; i < 32; i++)
  561.             sendata[i] = 0;
  562.         if ((ret = mdsense(dev, 3, 0, 32, sendata)) == OK)    {
  563.             if((msiz=get3bytes(sendata+5)))    {
  564.                         delay();
  565.                         Super(ostack);
  566.                         goto chkend;
  567.             }
  568.         }
  569.         msiz = size;
  570.         delay();
  571.         Super(ostack);
  572.         goto chkerr;
  573.     }
  574.  
  575.     ostack = Super(NULL);
  576.     /* Get format parameters/ disk size from media */
  577.     set = typedev & (mask << dev);
  578.     scsidrv = typedrv & (mask << dev);
  579.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  580.     if ((set) || (scsidrv))    {
  581.         for (i = 0; i < 32; i++)
  582.             sendata[i] = 0;
  583.         mdsense(dev, 0, 0, bsiz, sendata);
  584.         if((msiz=get3bytes(sendata+5)))    {
  585.                     delay();
  586.                     Super(ostack);
  587.                     goto chkend;
  588.         }
  589. redopg:
  590.         for (i = 0; i < 32; i++)
  591.             sendata[i] = 0;
  592.         ret = mdsense(dev, page, 0, 32, sendata);/* use page code 4, but get */
  593.                                             /* info from the mdsense header */
  594.         for (i = 0; i < 32; i++)
  595.             if (sendata[i])
  596.                 break;
  597.         if ((i==32) && (page == 4))        {
  598.             page = 3;
  599.             goto redopg;
  600.         } else if (i == 32)    {
  601.             msiz = size;
  602.             delay();
  603.             Super(ostack);
  604.             goto chkend;
  605.         }
  606.         if (!(msiz = get3bytes(sendata+5)))    {
  607.             if (page == 4)    {
  608.                 page = 3;
  609.                 /*
  610.                 cyl = get3bytes(sendata+14);
  611.                 head = *(sendata+17);
  612.                 */
  613.                 goto redopg;
  614.             } else {
  615.                 /*
  616.                 spt = getword(sendata+22);
  617.                 msiz = cyl * head * spt;
  618.                 */
  619.                 msiz = size;
  620.             }
  621.         }
  622.         delay();
  623.         Super(ostack);
  624.         goto chkend;
  625.     } else    {
  626.         ret = mdsense(dev, 0, 0, 22, sendata);
  627.         delay();
  628.         Super(ostack);
  629.  
  630.         /* If full SCSI, will return number of blocks */
  631.         /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  632.         /* will return 0 for number of blocks on disk */
  633.         /* on SCSI. */
  634.  
  635.             if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  636.             /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  637.             mb = (SETMODE *)sendata;
  638.             /* get number of cylinders */
  639.             cyl = mb->smd_cc[0];
  640.             cyl <<= 8;
  641.             cyl |= mb->smd_cc[1];
  642.     
  643.             /* get number of heads */
  644.             head = mb->smd_dhc;
  645.     
  646.             msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  647.     
  648.             for (i = 0; i < 20; i++) {
  649.                 if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  650.                     /* find out whether data has been transferred, by
  651.                           checking if dma pointer has been moved.      */
  652.  
  653.                     ostack = Super(NULL);
  654.                     delay();
  655.                     dmaptr = *dmahigh;
  656.                     dmaptr &= 0x0000003f;
  657.                     dmaptr <<= 16;
  658.                     tmpptr = *dmamid;
  659.                     tmpptr &= 0x000000ff;
  660.                     tmpptr <<= 8;
  661.                     dmaptr |= tmpptr;
  662.                     tmpptr = *dmalow;
  663.                     tmpptr &= 0x000000ff;
  664.                     dmaptr |= tmpptr;
  665.                     delay();
  666.                     Super(ostack);
  667.  
  668.                     if (dmaptr != buf)
  669.                         break;
  670.                    } else {            /* rdsects return an error */
  671.                     if (tsterr(ret) == OK) {
  672.                            break;
  673.                     }
  674.                 }
  675.             }
  676.     
  677.             if (ret == MDMCHGD)        /* check if error occurred */
  678.                 return (ret);
  679.        
  680.             /* Determine if media is MFM or RLL */
  681.             if (i < 20)    {
  682.                 msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  683.                 goto chkend;
  684.             }
  685.         }
  686.     }
  687. chkerr:
  688.     if (ret != 0) {
  689.         ret = errcode(dev);
  690.         if (tsterr(ret) != OK) 
  691.             return ERROR;
  692.         return (-3);    /* don't have to show the alert box */
  693.     }
  694. chkend:
  695.     if (size != msiz)
  696.         ret = ERROR;
  697.     else 
  698.         ret = OK;
  699.         
  700.     return (ret);
  701. }
  702.  
  703. /*
  704.  * Chkparm()
  705.  *    Check if given logical device has the asssumed parameters.
  706.  * Assumptions are:
  707.  *    - 512 bytes/sector
  708.  *    - 2 sectors/cluster
  709.  *    - 1 reserved sector
  710.  *    - 2 FATs
  711.  *
  712.  * Input:
  713.  *    ldev - logical device number ('C' -> 'P').
  714.  *
  715.  * Return:
  716.  *    OK - parameters of partition match the assumptions
  717.  *    ERROR - something went wrong.
  718.  *
  719.  * Comment:
  720.  *    Number of FATs is assumed to be 2.  Cannot check this 
  721.  * because previous version of HDX did not put that in the boot
  722.  * sector.
  723.  */
  724. chkparm(ldev)
  725. int ldev;
  726. {
  727.     char bs[512];        /* boot sector */
  728.     BOOT *boot;            /* boot structure */
  729.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  730.     int ret;
  731.  
  732.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  733.         if (tsterr(ret) != OK)
  734.             err(bootread);
  735.         ret = ERROR;
  736.         goto parmend;
  737.     }    
  738.  
  739.     boot = (BOOT *)bs;
  740.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  741.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  742.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  743.     if (bps % BPS            /* bytes per sector == ratio of 512 ? */
  744.     || res != 1) {            /* num sectors reserved == 1 ? */
  745.     ret = ERROR;            /* Nope, different from assumptions */
  746.     goto parmend;
  747.     }
  748.     
  749.     /* Check if sectors per cluster make sense */
  750.     if (boot->b_spc != 2) {
  751.         ret = ERROR;
  752.         goto parmend;
  753.     }
  754.     
  755.     ret = OK;                /* If yes, return OK */
  756.  
  757. parmend:
  758.     return ret;
  759. }
  760.  
  761.  
  762. ichkparm(ldev)
  763. int ldev;
  764. {
  765.     char bs[512];        /* boot sector */
  766.     BOOT *boot;            /* boot structure */
  767.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  768.     int ret;
  769.  
  770.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  771.         if (tsterr(ret) != OK)
  772.             err(bootread);
  773.         ret = ERROR;
  774.         goto parmend;
  775.     }    
  776.  
  777.     boot = (BOOT *)bs;
  778.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  779.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  780.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  781.     if (bps != 512            /* bytes per sector == 512 ? */
  782.     || res != 1) {            /* num sectors reserved == 1 ? */
  783.     ret = ERROR;            /* Nope, different from assumptions */
  784.     goto parmend;
  785.     }
  786.     
  787.     /* Check if sectors per cluster make sense */
  788.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  789.         (siz < 0x8000L && boot->b_spc != 2)) {
  790.         ret = ERROR;
  791.         goto parmend;
  792.     }
  793.     
  794.     ret = OK;                /* If yes, return OK */
  795.  
  796. parmend:
  797.     return ret;
  798. }
  799.  
  800.  
  801. /*
  802.  * Get dev's root block.
  803.  *
  804.  */
  805. getroot(dev, buf, sect)
  806. int dev;
  807. char *buf;
  808. SECTOR sect;
  809. {
  810.     return rdsects(dev, 1, buf, sect);
  811. }
  812.  
  813.  
  814. /*
  815.  * Put dev's root block.
  816.  *
  817.  */
  818. putroot(dev, buf, sect)
  819. int dev;
  820. char *buf;
  821. SECTOR sect;
  822. {
  823.     return wrsects(dev, 1, buf, sect);
  824. }
  825.  
  826.  
  827. /*
  828.  *  Read sector(s) from dev.
  829.  *
  830.  *  Input:
  831.  *    dev - device number (logical or physical).
  832.  *    num - number of sectors to read.
  833.  *    buf - buffer to write data read.
  834.  *    sect - starting sector number to read from.
  835.  *
  836.  *  Return:
  837.  *    errnum - 0: if read is successful.
  838.  *         an error code: if read is unsuccessful.
  839.  */
  840. rdsects(dev, num, buf, sect)
  841. int dev;            /* device number (logical or physical) */
  842. UWORD num;            /* number of sectors to read */
  843. char *buf;
  844. SECTOR sect;            /* starting sector to read from */
  845. {
  846.     int errnum;
  847.  
  848.     if (log2phys(&dev, §) < 0)
  849.     return ERROR;
  850.  
  851.     ostack = Super(NULL);
  852.     if (dev == 16)    { /* it is a AT drive */
  853.         errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  854.     } else {
  855.         errnum = hread(sect, num, buf, (UWORD)dev);
  856.     }
  857.     /*
  858.     if (errnum == 04)    {      the drive is stop 
  859.         delay();
  860.         stunt();
  861.         delay();
  862.         errnum = hread(sect, num, buf, (UWORD)dev);
  863.     }
  864.     */
  865.     delay();
  866.     Super(ostack);
  867.  
  868.     if (errnum > 0) {
  869.         errnum = errcode(dev);
  870.     }
  871.         
  872.     return errnum;        /* return the error code */
  873. }
  874.  
  875.  
  876. /*
  877.  *  Write sector(s) to dev.
  878.  *
  879.  *  Input:
  880.  *    dev - device number (logical or physical).
  881.  *    num - number of sectors to write.
  882.  *    buf - buffer with data to be written.
  883.  *    sect - starting sector number to write to.
  884.  *
  885.  *  Return:
  886.  *    errnum - 0: if write is successful.
  887.  *         an error code: if write is unsuccessful.
  888.  */
  889. wrsects(dev, num, buf, sect)
  890. int dev;            /* device number (logical or physical */
  891. UWORD num;            /* number of sectors to write */
  892. char *buf;            /* buffer with data to be written */
  893. SECTOR sect;            /* starting sector to write to */
  894. {
  895.     int errnum;
  896.  
  897.     if (log2phys(&dev, §) < 0)
  898.     return ERROR;
  899.  
  900.     ostack = Super(NULL);
  901.     if (dev == 16)    { /* it is a AT drive */
  902.         errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  903.     } else {
  904.         errnum = hwrite(sect, num, buf, (UWORD)dev);
  905.     }
  906.     delay();
  907.     Super(ostack);
  908.  
  909.     if (errnum > 0) {
  910.         errnum = errcode(dev);
  911.     }
  912.  
  913.     return errnum;
  914. }
  915.  
  916.  
  917. /*
  918.  * Zero range of sectors on dev.
  919.  *
  920.  */
  921. zerosect(dev, start, count)
  922. int dev;
  923. SECTOR start;
  924. UWORD count;
  925. {
  926.     char *zbuf;
  927.     int  v;
  928.     UWORD i;
  929.  
  930.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  931.         return err(nomemory);
  932.         
  933.     if (log2phys(&dev, &start) < 0) {
  934.         free(zbuf);
  935.     return ERROR;
  936.     }
  937.  
  938.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  939.  
  940.     while (count)
  941.     {
  942.         if (count > ZCOUNT)
  943.             i = ZCOUNT;
  944.         else i = count;
  945.  
  946.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  947.         break;
  948.     start += i;
  949.     count -= i;
  950.     }
  951.     free(zbuf);
  952.     
  953.     return v;
  954. }
  955.